package QueueP;

//循环队列=
public class LoopQueue<E> implements Queue<E>{

    private E[] data;   //存储数据的数组
    private int front;  //队列头
    private int tail;   //队列尾元素的下一个位置
    private int size;   //记录数据总长度

    public LoopQueue(int capacity){
        data=(E[])new Object[capacity+1];
        front=0;
        tail=0;
        size=0;
    }

    public LoopQueue(){
        this(10);
    }

    public int getCapacity(){
        return data.length-1;
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public boolean isEmpty() {

        return front==tail;
    }

    @Override
    public void enqueue(E e) {
        if((tail+1)%data.length==front){
            resize(getCapacity()*2);
        }
        data[tail]=e;
        tail=(tail+1)%data.length;
        size++;
    }

    @Override
    public E dequeue() {
        if(isEmpty()){
            throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
        }
        E ret=data[front];
        data[front]=null;
        front=(front+1)%data.length;
        size--;

        if (size==getCapacity()/4&&getCapacity()/2!=0){
            resize(getCapacity()/2);
        }
        return ret;
    }

    @Override
    public E getFront() {
        if(isEmpty()){
            throw new IllegalArgumentException("QueueP.Queue is empty.");
        }
        return data[front];
    }

    private void resize(int newCapacity){
        E[] newData=(E[])new Object[newCapacity+1];
        for (int i=0;i<size;i++){
            newData[i]=data[(i+front)%data.length];

        }
        data=newData;
        front=0;
        tail=size;
    }

    @Override
    public String toString(){
        StringBuffer res = new StringBuffer();
        res.append(String.format("QueueP.Queue: size =%d ,capacity =%d\n",size,getCapacity()));
        res.append("front [");
        for (int i=front;i!=tail;i=(i+1)%data.length){
            res.append(data[i]);
            if ((i+1)%data.length!=tail){
                res.append(",");
            }

        }
        res.append("] tail");
        return res.toString();

    }

    public static void main(String[] args) {
        LoopQueue<Integer> queue = new LoopQueue<>(5);
        for (int i=0;i<10;i++){
            queue.enqueue(i);
            System.out.println(queue);
//            if(i%3==2){
//                queue.dequeue();
//                System.out.println(queue);
//            }
            System.out.println(queue.getSize());
        }

    }



}
